package com.cuotigou.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.cuotigou.config.ConfigUtils;
import com.cuotigou.config.PayConfig;
import com.cuotigou.mapper.SRechargeListMapper;
import com.cuotigou.mapper.SUserChargeMapper;
import com.cuotigou.mapper.SUserMapper;
import com.cuotigou.pojo.SRechargeList;
import com.cuotigou.pojo.SUser;
import com.cuotigou.pojo.SUserCharge;
import com.cuotigou.pojo.WePayCallBackResult;
import com.cuotigou.service.PayService;
import com.cuotigou.util.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.security.krb5.Config;

import javax.net.ssl.*;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.util.*;

/**
 * Created by Administrator on 2019/1/16.
 */
@Controller
@RequestMapping("/pay")
public class PayController {

    private static final Logger LOG = LoggerFactory.getLogger(PayController.class);

    @Autowired
    private PayService payService;
    @Autowired
    private SUserChargeMapper sUserChargeMapper;
    @Autowired
    private SUserMapper sUserMapper;
    @Autowired
    private SRechargeListMapper sRechargeListMapper;

    /**
     * 购买vip
     * @param xmlBean
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/vip")
    @ResponseBody
    public ObjectResult vip(XMLBean xmlBean,HttpServletRequest request) throws Exception {
        if (StringUtil.isEmpty(xmlBean.getToken())) {
            return ObjectResult.build("0", "未登录");
        }
        if("1".equals(xmlBean.getType())) {
            return payService.aliPay(xmlBean);
        }
        if ("2".equals(xmlBean.getType())){
            String ip = CodeUtils.getIpAddress(request);
            return payService.weixin(xmlBean,ip);
        }
        return ObjectResult.build("0","参数丢失");
    }

    /**
     * 支付宝购买vip回调
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/aliPayNotify")
    @ResponseBody
    public String aliPayNotify(HttpServletRequest request) throws Exception{
        String sign = request.getParameter("sign");
        LOG.info("sign------"+sign);

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
//            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)

        LOG.info("map------"+params.toString());
        String fileRead = FileUtil.fileRead(PayConfig.ALIPAY_PUBLIC_KEY);
        String charset = params.get("charset");
        String sign_type = params.get("sign_type");

        LOG.info("fileRead------"+fileRead);

        boolean flag = AlipaySignature.rsaCheckV1(params, fileRead, charset,sign_type);

        LOG.info("flag------"+flag);
//        if(!flag){
//            LOG.info("验证签名失败");
//            return "fail";
//        }
        payService.aliPayNotify(params);

        return "success";
    }

    /**
     * 微信回调
     * @param request
     * @param modelMap
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/weixinNotify")
    @ResponseBody
    public Object weixinNotify(HttpServletRequest request, ModelMap modelMap) throws Exception {
        WePayCallBackResult result = new WePayCallBackResult(true, "", "");
        String successXml = "<xml>"
                + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml>";
        String orderNo = "";
        String resultCode = "";
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader br;
            // 【1】读取xml数据
            br = new BufferedReader(new InputStreamReader(
                    (ServletInputStream) request.getInputStream()));
            String line = null;

            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            LOG.error(MessageFormat.format(
                    "微信支付回调,订单号{0},订单支付结果{1},微信报文{2}", new Object[] { "",
                            resultCode, sb.toString() }));

            //微信开放平台审核通过的应用APPID
            String appid = PayConfig.WEIXIN_APPID;
            //微信支付分配的商户号
            String mch_id = PayConfig.MCH_ID;
            //key为商户平台设置的密钥key
            String appKey = PayConfig.APP_KEY;
            ParamsUtil paramsUtil = new ParamsUtil();
            String bank_type = StringUtil.substringBetween(
                    paramsUtil.getValue("bank_type", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String cash_fee = StringUtil.substringBetween(
                    paramsUtil.getValue("cash_fee", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String fee_type = StringUtil.substringBetween(
                    paramsUtil.getValue("fee_type", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String is_subscribe = StringUtil.substringBetween(
                    paramsUtil.getValue("is_subscribe", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String openid = StringUtil.substringBetween(
                    paramsUtil.getValue("openid", sb.toString()), "<![CDATA[",
                    "]]>",0);
            String out_trade_no = StringUtil.substringBetween(
                    paramsUtil.getValue("out_trade_no", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String result_code = StringUtil.substringBetween(
                    paramsUtil.getValue("result_code", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String return_code = StringUtil.substringBetween(
                    paramsUtil.getValue("return_code", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String time_end = StringUtil.substringBetween(
                    paramsUtil.getValue("time_end", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String total_fee = paramsUtil.getValue("total_fee", sb.toString());
            String trade_type = StringUtil.substringBetween(
                    paramsUtil.getValue("trade_type", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String transaction_id = StringUtil.substringBetween(
                    paramsUtil.getValue("transaction_id", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String nonce_str = StringUtil.substringBetween(
                    paramsUtil.getValue("nonce_str", sb.toString()),
                    "<![CDATA[", "]]>",0);
            String callBackSign = StringUtil.substringBetween(
                    paramsUtil.getValue("sign", sb.toString()), "<![CDATA[",
                    "]]>",0);

            Map<String, String> params = new HashMap<String, String>();
            params.put("appid", appid);
            params.put("mch_id", mch_id);
            params.put("bank_type", bank_type);
            params.put("cash_fee", cash_fee);
            params.put("fee_type", fee_type);
            params.put("is_subscribe", is_subscribe);
            params.put("openid", openid);
            params.put("out_trade_no", out_trade_no);
            params.put("result_code", result_code);
            params.put("return_code", return_code);
            params.put("time_end", time_end);
            params.put("total_fee", total_fee);
            params.put("trade_type", trade_type);
            params.put("transaction_id", transaction_id);
            params.put("nonce_str", nonce_str);
            String sign = PaymentKit.createSign(params, appKey);
            String orderStr = paramsUtil
                    .getValue("out_trade_no", sb.toString());
            orderNo = StringUtil
                    .substringBetween(orderStr, "<![CDATA[", "]]>",0);
            if (!callBackSign.equals(sign)) {
                LOG.info("微信回调验签失败");
                return successXml;
            }

            String returnCode = paramsUtil.getValue("return_code",
                    sb.toString());
            if (StringUtil.contains(returnCode, "SUCCESS")) {
                resultCode = paramsUtil.getValue("result_code", sb.toString());
            }
            Date payTime = null;
            if (StringUtil.contains(resultCode, "SUCCESS")) {
                result.setReturn_code("SUCCESS");
                payTime = new Date();
            } else {
                result.setReturn_code("FAIL");
            }

            LOG.error(MessageFormat.format(
                    "微信支付回调,订单号{0},订单支付结果{1},微信报文{2}", new Object[] { orderNo,
                            resultCode, sb.toString() }));
            // 查询是否有该订单
            SUserCharge sUserCharge = sUserChargeMapper.selectByOrderNo(orderNo);

            // 1.如果已经通知过了 直接给微信返回成功
            if (null != sUserCharge && sUserCharge.getStatus().equals("2")) {
                LOG.info("重复的回调");
                return successXml;
            }

            //修改订单状态
            sUserCharge.setStatus("2");
            sUserChargeMapper.updateByPrimaryKeySelective(sUserCharge);

            SUser sUser = sUserMapper.selectByPrimaryKey(sUserCharge.getUserId());
            Date vipTime = sUser.getExpireTime();

            //修改vip时间
            SRechargeList sRechargeList = sRechargeListMapper.selectByPrimaryKey(sUserCharge.getRechargeId());
            //未购买过vip或已过期直接从当前时间算起
            if (vipTime==null ||vipTime.compareTo(new Date())<0){
                vipTime = DateUtil.addDateDay(new Date(), sRechargeList.getRecharge().intValue());
            }else {
                //未过期从过期时间算起
                vipTime = DateUtil.addDateDay(vipTime, sRechargeList.getRecharge().intValue());
            }
            sUser.setExpireTime(vipTime);
            sUser.setIsVip(1);
            sUserMapper.updateByPrimaryKeySelective(sUser);

            return successXml;
        } catch (Exception e) {
            LOG.info("微信回调失败");
            ExceptionUtil.logError(e,LOG);

        }
        return "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[FAIL]]></return_msg>" + "</xml>";
    }

    /**
     * ios购买vip
     * @param request
     * @param xmlBean
     * @return
     */
    @RequestMapping(value = "/iosApplePay", method = RequestMethod.POST)
    @ResponseBody
    public ObjectResult iosApplePay(HttpServletRequest request,
                                    XMLBean xmlBean) {
        final String receipt = request.getParameter("receipt");
        final String userId = CommonUtils.decToken(xmlBean.getToken());
        final String productId = request.getParameter("productId");

        //测试环境
//        String verifyResult = applePayUtil.buyAppVerifyForSand(receipt);
        //正式环境
        String verifyResult = applePayUtil.buyAppVerifyForVerify(receipt);
        JSONObject jsonObject = JSON.parseObject(verifyResult);

        if(verifyResult == null){
            return ObjectResult.build("0","无订单信息");
        }

        String states = jsonObject.getString("status");
        //成功
        if (states.equals("0")){
            //验证订单
            String r_receipt = jsonObject.getString("receipt");
            JSONObject returnJson = JSON.parseObject(r_receipt);
            String product_id = returnJson.getString("product_id");
            if(!productId.equals(product_id)){
                return ObjectResult.build("0","订单号不一致");
            }
            return payService.applePay(userId,productId);
        } else {
            return ObjectResult.build("0","验证失败");
        }

    }
}
